#include "stdio.h"
#include "stdint.h"
#include "stdlib.h"

#define PLIC_BASE 0x0c000000

// 定义控制状态寄存器的地址
#define MSTATUS_MIE (1 << 3)  // MIE 位的掩码
#define MIE_MTIE (1 << 7)     // Timer Interrupt Enable

extern void my_printf(const char *fmt, ...);

static inline void enable_global_interrupts() {
    // 读取 mstatus 寄存器的值
    uint64_t mstatus;
    asm volatile("csrr %0, mstatus" : "=r"(mstatus));
    
    // 设置 MIE 位
    mstatus |= MSTATUS_MIE;
    
    // 写回 mstatus 寄存器
    asm volatile("csrw mstatus, %0" : : "r"(mstatus));
}

void print_string(const char *str) {
    while (*str) {
        *((volatile char *)0x10000000) = *str++; // 模拟 UART 输出
    }
}
void print_num(unsigned char *str, int n){
    for(int i=0; i<n;i++){
    *((volatile char *)0x10000000) = *str++; // 模拟 UART 输出
	}
}
int _write (int file, char * ptr, int len) {
	int i;

	/* Turn character to capital letter and output to UART port */
	for (i = 0; i < len; i++) *((volatile char *)0x10000000) = *ptr++;;

	//uart_putc('\r');
	return len;
}

void plic_init() {
    // 初始化 PLIC
    // 设置中断优先级
    // plic_set_priority(1, 1); // 设置设备 1 的优先级为 1
    for(int i=0;i<32;i++){
    *(uint32_t *)(PLIC_BASE+0x04*i) = 1; // 设置设备 1 的优先级为 1
}
    // 使能中断
    // plic_enable_interrupt(1); // 使能设备 1 的中断
    *(uint32_t *)(PLIC_BASE+0x2000) = 0xFFFFFFFF;
    *(uint32_t *)(PLIC_BASE+0x2004) = 0xFFFFFFFF;
    *(uint32_t *)(PLIC_BASE+0x2008) = 0xFFFFFFFF;
    *(uint32_t *)(PLIC_BASE+0x200c) = 0xFFFFFFFF;
    *(uint32_t *)(PLIC_BASE+0x2010) = 0xFFFFFFFF;

    // 启用 M-mode 外部中断（mie 寄存器的 MEIE 位）
    asm volatile("csrs mie, %0" : : "r"(1 << 11)); // MEIE = bit 11
    // 启用全局中断（mstatus 的 MIE 位）
    asm volatile("csrs mstatus, %0" : : "r"(1 << 3)); // MIE = bit 3
}

uint32_t plic_claim() {
    uint32_t claim_addr = PLIC_BASE + 0x200004;  // 每个 hart 有独立的偏移地址
    return *(volatile uint32_t *)claim_addr;
    
}

static inline void plic_complete(uint32_t irq_id) {
    uint32_t complete_addr = PLIC_BASE + 0x200004;  // 使用相同的偏移地址
    *(volatile uint32_t *)complete_addr = irq_id;
}

void interrupt_handler() {
    uint32_t claim = plic_claim();
    if (claim) {
        print_string("Handling interrupt from device ");
        print_num((unsigned char *)(&claim), 4);
        // 处理中断
        plic_complete(claim);
    }
}

void setup_trap(void) {
    // 设置 mtvec 为 trap_handler 地址（直接模式）
    asm volatile("csrw mtvec, %0" : : "r"(&interrupt_handler));
}

int main() {
    print_string("Hello, RISC-V!\n");
    //printf("hello world\n");
    plic_init();
    setup_trap();
    unsigned int a;
    a = *(volatile unsigned int *)0x6000000;
    print_num((unsigned char *)(&a), 4);
    a = *(volatile unsigned int *)0x6000004;
    print_num((unsigned char *)(&a), 4);
    // = *(volatile unsigned int *)0x6000008;
    //print_num((unsigned char *)(&a), 4);
    //a = *(volatile unsigned int *)0x600000c;
    *(volatile unsigned int *)0x6000008=0xdeadbeef;
    *(volatile unsigned int *)0x6000080=0xdeadbeef;
    
    my_printf("Hello, %s! Number: %d, Hex: %x, Char: %c\n", "world", 123, 0xABCD, 'A');
    while(1){
        // 检查和处理中断
        // interrupt_handler();
    }
    return 0;
}
